# -*- coding: utf-8 -*-


# 数据结构
# joinerList = [
#   {'firstpeople': {'do': ['task1', 'task3', 'task4', 'task5']}},
#   {'secondpeople': {'do': ['task2', 'task3', 'task5']}},
#   {'thirdpeople': {'do': ['task3', 'task4', 'task6']}},
#   {'thirdpeople': {'do': ['task3', 'task4', 'task6']}},
# ]
# taskList = {
#   'task1': 'value1',
#   'task2': 'value2',
#   'task3': 'value3',
#   'task4': 'value4',
#   ....
# }
# 报名者 >= 2
def mseningAuction(joinerList, taskList):
    # 函数参数－－用户列表以及用户能够完成的任务情况
    joinerList = {
        'firstpeople': {'do': ['task1', 'task3', 'task4', 'task5'], 'value': 8},
        'secondpeople': {'do': ['task2', 'task3', 'task5'], 'value': 6},
        'thirdpeople': {'do': ['task3', 'task4', 'task6'], 'value': 6},
        'fourthpeople': {'do': ['task3'], 'value': 5},
    }
    # 函数参数－－任务列表
    taskList = {
        'task1': 3,
        'task2': 8,
        'task3': 6,
        'task4': 8,
        'task5': 10,
        'task6': 9,
    }
    # 函数运行的前提条件　报名者 >= 2
    if len(joinerList) < 2:
        return {'status': 'error', 'msg': '人数小于2'}

    # 被选中的用户列表
    winner = []
    # 没被选中的用户列表
    failed = []
    for join in joinerList:
        failed.append(join)

    # while winner != failed:
        joinerValue = {}
        for user in failed:
            if user in winner:
                continue
            tempList = winner[:]
            winnerTask = []
            for tmp in tempList:
                winnerTask += joinerList.get(tmp).get('do')
            winnerTask = list(set(winnerTask))
            winnerValue = getTaskListValue(winnerTask, taskList)
            print winnerValue
            tempList.append(user)
            doTaskList = []
            for tmp in tempList:
                doTaskList += joinerList.get(tmp).get('do')
            doTaskList = list(set(doTaskList))
            print doTaskList
            value = 0
            for task in doTaskList:
                value += taskList.get(task)
            selfValue = value - winnerValue - joinerList.get(user).get('value')
            joinerValue.setdefault(user, selfValue)

        winuser = getJoinerWinner(joinerValue)

        if winuser['winner'] not in winner and winuser['value'] > 0:
            winner.append(winuser['winner'])


    print 'payment joinerlist'
    winnerPayment = {}
    for joiner in winner:
        defaultJoiner = [x for x in winner if x != joiner]
        defaultWinner = []
        maxDefaultValue = {'value': 0, 'user': joiner}
        print [x for x in defaultJoiner if x not in defaultWinner]
        for user in [x for x in defaultJoiner if x not in defaultWinner]:
            tempList = defaultWinner[:]
            tempList.append(joiner)
            # tempList.append(user)
            # 计算Ｖ2(1)-(V3(1)-b3)
            # 计算V2(1) = V(1,2)-V(1)
            # 计算V(1,2)
            taskValue = getDoTaskList(joinerList, tempList, taskList)
            # 计算V(1)
            defaultValue = getDoTaskList(joinerList, defaultWinner, taskList)
            defaultWinner.append(user)

            # 计算V3(1) = V(1,3)-V(1)
            # 计算V(1,3)
            pushValue = getDoTaskList(joinerList, defaultWinner, taskList)

            # 计算V2(1)-(V3(1)-b3) = V(1,2)-V(1)-V3(1)+b3 = V(1,2)-V(1)-V(1,3)-V(1)+b3
            defaultPayment = taskValue.get('value') - defaultValue.get('value') - pushValue.get('value') - defaultValue.get('value') + joinerList.get(user).get('value')
            if maxDefaultValue.get('value') < defaultPayment:
                maxDefaultValue['value'] = defaultPayment
        else:
            # 计算V2(1,3) = V(1,2,3)-V(1,3)
            tempList = defaultWinner[:]
            tempList.append(joiner)
            # 计算V(1,2,3)
            taskValue = getDoTaskList(joinerList, tempList, taskList)
            # 计算V(1,3)
            defaultValue = getDoTaskList(joinerList, defaultWinner, taskList)

            finalPayment = taskValue.get('value') - defaultValue.get('value')
            if maxDefaultValue.get('value') < finalPayment:
                maxDefaultValue['value'] = finalPayment

            winnerPayment.setdefault(joiner, maxDefaultValue.get('value'))

    return {'winner': winner, 'payment': winnerPayment}


def getJoinerWinner(joinerValue):
    winner = {'winner': 'winner', 'value': 0}
    for value in joinerValue:
        if joinerValue.get(value) > winner.get('value'):
            winner['value'] = joinerValue.get(value)
            winner['winner'] = value
    return winner


# 计算用户能够完成任务的总价值
def getTaskListValue(doTaskList, taskList):
    value = 0
    for task in doTaskList:
        value += taskList.get(task)
    return value


# 计算用户能够完成的任务列表以及价值
def getDoTaskList(joinerList, userList, taskList):
    doTaskList = []
    for user in userList:
        doTaskList += joinerList.get(user).get('do')
    doTaskList = list(set(doTaskList))
    value = 0
    for task in doTaskList:
        value += taskList.get(task)
    return {'dotasklist': doTaskList, 'value': value}


# 每一个子任务至少两个人报名
# 数据结构
#
def tracAuction(joinerList, taskList):
    joinerList = {
        'firstpeople': {'do': ['task1', 'task3', 'task4', 'task5'], 'value': 8},
        'secondpeople': {'do': ['task2', 'task3', 'task5'], 'value': 6},
        'thirdpeople': {'do': ['task3', 'task4', 'task6'], 'value': 6},
        'fourthpeople': {'do': ['task3'], 'value': 5},
    }
    taskList = {
        'task1': 3,
        'task2': 8,
        'task3': 6,
        'task4': 8,
        'task5': 10,
        'task6': 9,
    }

    if not isConfirm(joinerList, taskList):
        return {'status': 'error', 'msg': '每个子任务至少有两人报名'}

    defaultTaskList = taskList.keys()
    defaultWinner = []
    print defaultTaskList
    while len(defaultTaskList) > 0:
        defaultJoiner = [x for x in joinerList if x not in defaultWinner]
        print defaultJoiner
        minDefaultValue = {'user': 'user', 'value': 10000, 'dotask': []}
        for user in defaultJoiner:
            userValue = getUserValue(defaultTaskList, joinerList, taskList, user)
            userValueArg = (joinerList.get(user).get('value') + 0.0) / userValue.get('value')
            if minDefaultValue.get('value') > userValueArg:
                minDefaultValue['user'] = user
                minDefaultValue['value'] = userValueArg
                minDefaultValue['dotask'] = userValue.get('dotask')
        defaultWinner.append(minDefaultValue.get('user'))
        defaultTaskList = [x for x in defaultTaskList if x not in minDefaultValue.get('dotask')]

    print defaultWinner
    joinerPayment = {}
    for joiner in joinerList:
        joinerPayment.setdefault(joiner, 0)

    for winner in defaultWinner:
        defaultJoiner = [x for x in joinerList if x != winner]
        defaultTaskList = taskList.keys()
        tempWinner = []
        while len(defaultTaskList) > 0:
            tempJoiner = [x for x in defaultJoiner if x not in tempWinner]
            minDefaultValue = {'user': 'user', 'value': 10000, 'dotask': []}
            for joiner in tempJoiner:
                userValue = getUserValue(defaultTaskList, joinerList, taskList, user)
                print userValue
                userValueArg = (joinerList.get(user).get('value') + 0.0) / userValue.get('value')
                if minDefaultValue.get('value') > userValueArg:
                    minDefaultValue['user'] = user
                    minDefaultValue['value'] = userValueArg
                    minDefaultValue['dotask'] = userValue.get('dotask')
            winnerValue = getUserValue(defaultTaskList, joinerList, taskList. winner)
            minWinnerValue = getUserValue(defaultTaskList, joinerList, taskList, minDefaultValue.get('user'))
            userValueArg = ((winnerValue + 0.0) / minWinnerValue) * joinerList.get(minDefaultValue.get('user'))
            if joinerPayment.get(winner) < userValueArg:
                joinerPayment[winner] = userValueArg
            tempWinner.append(minDefaultValue.get('user'))
            defaultTaskList = [x for x in defaultTaskList if x not in minDefaultValue.get('dotask')]

    print joinerPayment
    return {'winner': defaultWinner, 'payment': joinerPayment}


def isConfirm(joinerList, taskList):
    for task in taskList:
        count = 0
        for joiner in joinerList:
            if task in joinerList.get(joiner).get('do'):
                count += 1
        if count < 2:
            return False
    return True


def getUserValue(defaultTaskList, joinerList, taskList, user):
    doTaskList = joinerList.get(user).get('do')
    doTask = []
    value = 0
    print doTaskList
    for task in doTaskList:
        if task in defaultTaskList:
            value += taskList.get(task)
            doTask.append(task)
    return {'value': value, 'dotask': doTask}


# 带有预算的算法
#singerauction
# constraint => 预算
def singerAuction(joinerList, taskList, constraint):
    joinerList = {
        'firstpeople': {'do': ['task1', 'task3', 'task4', 'task5'], 'value': 8},
        'secondpeople': {'do': ['task2', 'task3', 'task5'], 'value': 6},
        'thirdpeople': {'do': ['task3', 'task4', 'task6'], 'value': 6},
        'fourthpeople': {'do': ['task3'], 'value': 5},
    }
    taskList = {
        'task1': 3,
        'task2': 8,
        'task3': 6,
        'task4': 8,
        'task5': 10,
        'task6': 9,
    }
    defaultTaskList = taskList.keys()
    defaultWinner = []

    book = True
    while book:
        defaultJoiner = [x for x in joinerList if x not in defaultWinner]
        maxDefaultValue = {'user': 'user', 'value': 0, 'doTask': 0}
        for user in defaultJoiner:
            tempJoiner = defaultWinner[:]
            tempJoiner.append(user)
            # Vj(S) = V(S && j) - V(S)
            # V(S && j)
            taskValue = getDoTaskList(joinerList, tempJoiner, taskList)
            # V(S)
            defaultValue = getDoTaskList(joinerList, defaultWinner, taskList)
            # Vj(S)
            userValue = taskValue.get('value') - defaultValue.get('value') + 0.0
            value = userValue / joinerList.get(user).get('value')
            if value > maxDefaultValue.get('value'):
                maxDefaultValue['value'] = value
                maxDefaultValue['doTask'] = (userValue * constraint) / taskValue.get('value')
                maxDefaultValue['user'] = user
        if maxDefaultValue.get('doTask') >= joinerList.get(maxDefaultValue.get('user')).get('value'):
            defaultWinner.append(maxDefaultValue.get('user'))
            book = True
        else:
            book = False
    print defaultWinner

    joinerListPayment = {}
    for joiner in joinerList:
        joinerListPayment.setdefault(joiner, 0)

    for winner in defaultWinner:
        # 此处没有进行排序，相应的下方是对全部用户进行遍历
        defaultJoiner = [x for x in joinerList if x != winner]
        tempWinner = []
        for joiner in defaultJoiner:
            tempJoiner = [x for x in defaultJoiner if x not in tempWinner]
            maxDefaultValue = {'user': 'user', 'value': 0, 'minvalue': 0}
            for user in tempJoiner:
                # V(Q j) = V(Q && j)
                tempWinner.append(user)

                taskValue = getDoTaskList(joinerList, tempWinner, taskList)

                tempWinner.pop()
                # V(Q j-1)
                defaultValue = getDoTaskList(joinerList, tempWinner, taskList)

                # V(Q j-1 && i)
                tempJoiner.append(winner)
                winnerValue = getDoTaskList(joinerList, tempJoiner, taskList)
                tempJoiner.pop()
                # V i(j)[Q j-1]
                winnerUserValue = winnerValue.get('value') - defaultValue.get('value') + 0.0
                # V j(Q j-1)
                userValue = taskValue.get('value') - defaultValue.get('value') + 0.0
                value = userValue / joinerList.get(user).get('value')
                nWinnerUserValue = winnerUserValue * constraint / winnerValue.get('value')
                try:
                    bugetWinnerUserValue = winnerUserValue * joinerList.get(user).get('value') / userValue
                except Exception as e:
                    bugetWinnerUserValue = nWinnerUserValue
                if value >= maxDefaultValue.get('value'):
                    maxDefaultValue['value'] = value
                    maxDefaultValue['user'] = user
                    if nWinnerUserValue < bugetWinnerUserValue:
                        maxDefaultValue['minvalue'] = nWinnerUserValue
                    else:
                        maxDefaultValue['minvalue'] = bugetWinnerUserValue
            print maxDefaultValue
            if joinerListPayment.get(maxDefaultValue.get('user')) < maxDefaultValue.get('minvalue'):
                joinerListPayment[maxDefaultValue.get('user')] = maxDefaultValue.get('minvalue')
            tempWinner.append(maxDefaultValue.get('user'))
    print joinerListPayment
    return {'winner': defaultWinner, 'payment': joinerListPayment}


def getSelfJoinerValue(taskList, joinerList, joiner):
    doTaskList = joinerList.get(joiner).get('do')
    value = 0
    for task in doTaskList:
        value += taskList.get(task)
    print value
